/******************************************************************************/
/*  This file is part of the Skomer Island firmware for the MSP430F1612       */
/******************************************************************************/
/*                                                                            */
/*  1-Wire support code, based on a public domain library by Dallas           */
/*                                                                            */
/******************************************************************************/

//---------------------------------------------------------------------------
// Copyright (C) 2003 Dallas Semiconductor Corporation, All Rights Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// Except as contained in this notice, the name of Dallas Semiconductor
// shall not be used except as stated in the Dallas Semiconductor
// Branding Policy.
//--------------------------------------------------------------------------
//
//  mbEE77.c - Reads and writes to memory locations for the EE memory bank
//             for the DS1977.
//  version 1.00
//

// Include Files
#include "OW_wrapper.h"

// General command defines
#define READ_MEMORY_PSW_COMMAND  0x69
#define WRITE_SCRATCHPAD_COMMAND 0x0F
#define READ_SCRATCHPAD_COMMAND  0xAA
#define COPY_SCRATCHPAD_COMMAND  0x55
// Local defines
#define PAGE_LENGTH_HYGRO 32

/**
 * ONE MEMORY PAGE HAS THE SIZE OF 32 BYTE
 * Read a complete memory page with CRC verification provided by the
 * device.  Not supported by all devices.  See the method
 * 'hasPageAutoCRCEE()'.
 *
 * bank     to tell what memory bank of the ibutton to use.
 * portnum  the port number of the port being used for the
 *          1-Wire Network.
 * SNum     the serial number for the part.
 * page     the page to read
 * rd_cont  if 'true' then device read is continued without
 *          re-selecting.  This can only be used if the new
 *          read() continious where the last one led off
 *          and it is inside a 'beginExclusive/endExclusive'
 *          block.
 * buff     byte array containing data that was read
 *
 * @return - returns '0' if the read page wasn't completed.
 *                   '1' if the operation is complete.
 */
SMALLINT readPageCRCEE77(SMALLINT bank, int portnum, uchar *SNum,
                         int page, uchar *buff)
{
	SMALLINT i, send_len=0, lsCRC16;
	uchar  raw_buf[15];
	int str_add;
	ushort lastcrc16;
	uchar psw[8];
	
	// set serial number of device to read
	owSerialNum(portnum,SNum,FALSE);
	
	// select the device
	if (!owAccess(portnum))
	{
		OWERROR(OWERROR_DEVICE_SELECT_FAIL);
		return FALSE;
	}
	
	// command, address, offset, password (except last byte)
	raw_buf[send_len++] = READ_MEMORY_PSW_COMMAND;

	str_add = page * PAGE_LENGTH_HYGRO;

	raw_buf[send_len++] = str_add & 0xFF;
	raw_buf[send_len++] = ((str_add & 0xFFFF) >> 8) & 0xFF;
	
	// calculate the CRC16
	setcrc16(portnum,0);
	for(i = 0; i < send_len; i++)
		lastcrc16 = docrc16(portnum,raw_buf[i]);
	
	for (i = 0; i < 8; i++)
		raw_buf[send_len++] = psw[i];
	
	if(!owBlock(portnum,FALSE,raw_buf,send_len)) // the command was not sent, failure
	{
		OWERROR(OWERROR_BLOCK_FAILED);
		return FALSE;
	}
	
	for(i=0; i<PAGE_LENGTH_HYGRO; i++) //clean up the page
		buff[i] = 0xFF;
	
	if(!owBlock(portnum,FALSE,buff,PAGE_LENGTH_HYGRO))
	{
		OWERROR(OWERROR_BLOCK_FAILED);
		return FALSE;
	}
	
	// read the first CRC16 byte
	lsCRC16 = owReadByte(portnum);
	
	// calculate CRC on data read
	for(i = 0; i < PAGE_LENGTH_HYGRO; i++)
	lastcrc16 = docrc16(portnum,buff[i]);
	
	// check lsByte of the CRC
	if ((lastcrc16 & 0xFF) != (~lsCRC16 & 0xFF))
	{
		OWERROR(OWERROR_CRC_FAILED);
		return FALSE;
	}
	
	return TRUE;
}
